#pragma once
#include"Singleton.h"
#include<boost/asio.hpp>
#include<vector>
#include<thread>
#include<mutex>
class AsioIOServicePool : public Singleton<AsioIOServicePool>
{
	friend class Singleton<AsioIOServicePool>;
public:
	using IOService = boost::asio::io_context;
	using WorkGuard = boost::asio::executor_work_guard<IOService::executor_type>;

	~AsioIOServicePool();
	AsioIOServicePool(const AsioIOServicePool&) = delete;
	AsioIOServicePool& operator=(const AsioIOServicePool&) = delete;
	boost::asio::io_context& GetIOService();
	void Stop();
private:
	AsioIOServicePool(std::size_t pool_size = std::thread::hardware_concurrency());
	std::vector<std::shared_ptr<IOService>> m_io_services;
	std::vector<WorkGuard> m_work_guards;
	std::vector<std::thread> m_threads;// threads to run io_services
	std::size_t m_next_io_service; // for round-robin
	std::mutex m_mutex; // to protect m_next_io_service or use atomic variable
};
